package service

import (
	"errors"
	"exercise/application/yiran/app"
	"exercise/application/yiran/app/model"
	"exercise/application/yiran/app/request"
	"fmt"
	"github.com/360EntSecGroup-Skylar/excelize"
	excelizeV2 "github.com/xuri/excelize/v2"
	"path/filepath"
	"reflect"
	"strings"
)

type excelService struct {
}

// Import excel导入
func (e *excelService) Import(request *request.ImportRequest) (map[int]string, []map[string]interface{}, error) {
	fileCenter := new(model.FileCenter)
	_ = model.NewDb("").FindOne(fileCenter, "id = ?", []interface{}{request.Id}, "*", nil)

	if fileCenter.SavePath == "" {
		return nil, nil, errors.New("文件不存在")
	}
	header, list, err := e.ReadExcel(fileCenter.SavePath, 1, 0)
	if list == nil {
		return nil, nil, errors.New("该文件为空,请重新上传")
	}
	//处理学生数据
	newList := make([]map[string]interface{}, 0)
	for _, val := range list {
		newList = append(newList, e.linkExcelStudent(val))
	}
	return header, newList, err
}

// ReadExcel  去读excel内容
// path 文件路径
// headerIndex 表头位置 默认为1
// desIndex    表描述位置 默认0 ,不存在表描述
func (e *excelService) ReadExcel(path string, headerIndex, desIndex int) (map[int]string, []map[string]interface{}, error) {
	path = filepath.Join(app.YiRanPublicDir, path)
	f, err := excelize.OpenFile(path)
	if err != nil {
		return nil, nil, err
	}
	//获取文件簿,默认处理第一个
	sheets := f.GetSheetMap()
	rows := f.GetRows(sheets[1])
	//表头数据
	header := make(map[int]string, 0)
	//列表数据
	list := make([]map[string]interface{}, 0)
	for i, row := range rows {
		if desIndex == 0 && i == desIndex && headerIndex != desIndex { //第一行是说明内容忽略
			continue
		}
		if i == headerIndex { //获取表头信息
			for k, v := range row {
				header[k] = v
			}
		} else {
			data := make(map[string]interface{}, 0)
			for key, val := range row {
				data[header[key]] = val
			}
			list = append(list, data)
		}
	}
	return header, list, nil
}

func (e *excelService) ReadExcelXlsx(path string) (map[int]string, []map[string]interface{}, error) {
	path = filepath.Join(app.YiRanPublicDir, path)
	extArr := strings.Split(path, ".")
	ext := extArr[len(extArr)-1]
	f, err := excelizeV2.OpenFile(path)
	if err != nil {
		return nil, nil, err
	}
	rows := make([][]string, 0)
	if ext == "xlsx" {
		//读取excel中的每一条数据
		rows, err = f.GetRows("Sheet1")
	}

	if err != nil {
		return nil, nil, err
	}

	//头部信息所在行数
	headerIndex := 0
	//表头数据
	header := make(map[int]string, 0)
	//列表数据
	list := make([]map[string]interface{}, 0)
	for i, row := range rows {
		if i == headerIndex { //获取表头信息
			for k, v := range row {
				header[k] = v
			}
			continue
		}
		data := make(map[string]interface{}, 0)
		for key, val := range row {
			data[header[key]] = val
		}
		list = append(list, data)
	}
	return header, list, nil
}

func (e *excelService) linkExcelStudent(value map[string]interface{}) map[string]interface{} {
	excelStudent := new(model.ExcelStudent)
	//获取excelStudent的属性，Elem() 获取地址(指针)所指的值
	excelStudentProperty := reflect.TypeOf(excelStudent).Elem()
	//获取excelStudent中的值
	excelStudentVal := reflect.ValueOf(excelStudent).Elem()

	fmt.Printf("type = %v \n", excelStudentProperty)
	fmt.Printf("有多少个属性 = %v \n", excelStudentProperty.NumField())
	fmt.Printf("有多少个属性 = %v \n", excelStudentVal.NumField())

	item := make(map[string]interface{}, 0)

	for i := 0; i < excelStudentProperty.NumField(); i++ {
		jsonTag := excelStudentProperty.Field(i).Tag.Get("json")
		ecl := excelStudentProperty.Field(i).Tag.Get("ecl")
		item[jsonTag] = value[ecl]
	}
	return item
}

func NewExcelService() *excelService {
	return &excelService{}
}
